#include "ObjectFactory.h"
#include <cassert>
#include "IEntity.h"
#include "Elemental.h"
#include "../SGD Wrappers/CSGD_TextureManager.h"
#include "ObjectManager.h"
#include "Tower.h"
#include "Avatar.h"
#include "GameplayState.h"
#include "Waypoint.h"
#include "Player.h"
#include "Node.h"
#include "TargetBox.h"

/*static*/ CObjectFactory*	CObjectFactory::GetInstance( void )
{
	// Dynamically allocate the instance (if needed)
	static CObjectFactory s_Instance;


	// Return the pointer
	return &s_Instance;
}

CObjectFactory::CObjectFactory(void)
{
}


CObjectFactory::~CObjectFactory(void)
{
}

void CObjectFactory::Init( void )
{
	m_pTM = CSGD_TextureManager::GetInstance();
	m_pOM = CObjectManager::GetInstance();

	tempFireImg =  m_pTM->LoadTexture(_T("Resources/Graphics/fire.png"),			D3DCOLOR_ARGB(255, 255,255,255));
	tempAirImg =  m_pTM->LoadTexture(_T("Resources/Graphics/Air.png"),				D3DCOLOR_ARGB(255, 255,255,255));
	tempWaterImg =  m_pTM->LoadTexture(_T("Resources/Graphics/Water.png"),			D3DCOLOR_ARGB(255, 255,255,255));
	tempEarthImg =  m_pTM->LoadTexture(_T("Resources/Graphics/Earth.png"),			D3DCOLOR_ARGB(255, 255,255,255));
	tempMagmaImg = m_pTM->LoadTexture(_T("Resources/Graphics/Magma.png"),			D3DCOLOR_ARGB(255, 255,255,255));
	tempKamikazeImg = m_pTM->LoadTexture(_T("Resources/Graphics/Kamikaze.png"),		D3DCOLOR_ARGB(255, 255,255,255));
	tempMudImg = m_pTM->LoadTexture(_T("Resources/Graphics/Mud.png"),				D3DCOLOR_ARGB(255, 255,255,255));
	tempSandImg = m_pTM->LoadTexture(_T("Resources/Graphics/Sand.png"),				D3DCOLOR_ARGB(255, 255,255,255));
	tempStormImg  = m_pTM->LoadTexture(_T("Resources/Graphics/Storm.png"),			D3DCOLOR_ARGB(255, 255,255,255));
	tempSteamImg  = m_pTM->LoadTexture(_T("Resources/Graphics/Steam.png"),			D3DCOLOR_ARGB(255, 255,255,255));
	tempMetalImg  = m_pTM->LoadTexture(_T("Resources/Graphics/Metal.png"),			D3DCOLOR_ARGB(255, 255,255,255));
	tempMortarImg  = m_pTM->LoadTexture(_T("Resources/Graphics/Mortor.png"),		D3DCOLOR_ARGB(255, 255,255,255));
	tempHurricaneImg  = m_pTM->LoadTexture(_T("Resources/Graphics/Hurricane.png"),	D3DCOLOR_ARGB(255, 255,255,255));
	tempEverestImg  = m_pTM->LoadTexture(_T("Resources/Graphics/Everest.png"),		D3DCOLOR_ARGB(255, 255,255,255));
	tempOmegaImg  = m_pTM->LoadTexture(_T("Resources/Graphics/Omega.png"),			D3DCOLOR_ARGB(255, 255,255,255));
	tempTowerImg =  m_pTM->LoadTexture(_T("Resources/Graphics/Tower.png"),			D3DCOLOR_ARGB(255, 255,255,255));
	tempAvatarImg =  m_pTM->LoadTexture(_T("Resources/Graphics/Avatar.png"),		D3DCOLOR_ARGB(255, 255,255,255));
	
	for( float i = 0; i < 15; i++ )
	{
		CElemental* tempElemental = new CElemental;
		tempElemental->SetImageID((int)(i+2));
		tempElemental->SetHeight(20);
		tempElemental->SetWidth(20);
		tempElemental->SetPosX(0+(i*200));
		tempElemental->SetPosY(100);
		tempElemental->SetHealth(100);
		tempElemental->SetAttackDamage(10);
		tempElemental->SetAttackSpeed(1);
		tempElemental->SetMoveSpeed(100);
		tempElemental->SetDefense(0);
		tempElemental->SetRange(0);

		AllGameObjects.push_back(tempElemental);
	}

	CTower* tempTower = new CTower;
	tempTower->SetImageID(tempTowerImg);
	tempTower->SetHeight(30);
	tempTower->SetWidth(30);
	tempTower->SetPosX(300);
	tempTower->SetPosY(100);
	AllGameObjects.push_back(tempTower);
	//delete tempTower;

	CAvatar* tempAvatar = new CAvatar;
	tempAvatar->SetImageID(tempAvatarImg);
	tempAvatar->SetHeight(100);
	tempAvatar->SetWidth(100);
	tempAvatar->SetPosX(500);
	tempAvatar->SetPosY(100);
	AllGameObjects.push_back(tempAvatar);
	//delete tempAvatar;

	m_pGS = CGameplayState::GetInstance();
}

void CObjectFactory::SpawnElemental( CPlayer* owner, short laneChoice)
{
	CElemental* tempElemental = new CElemental;
	
	vector<short> ElementalSouls = owner->GetQueue();
	Waypoints = m_pGS->LanePath(laneChoice);
	if( ElementalSouls[Fire] != 0 )
	{
	*tempElemental = *dynamic_cast<CElemental*>(AllGameObjects[Fire]);
	}
	if( ElementalSouls[Water] != 0 )
	{
	*tempElemental = *dynamic_cast<CElemental*>(AllGameObjects[Water]);
	}
	if( ElementalSouls[Air] != 0 )
	{
	*tempElemental = *dynamic_cast<CElemental*>(AllGameObjects[Air]);
	}
	if( ElementalSouls[Earth] != 0 )
	{
	*tempElemental = *dynamic_cast<CElemental*>(AllGameObjects[Earth]);
	}

	//Level 2
	if( ElementalSouls[Earth] != 0 && ElementalSouls[Fire] != 0)
	{
	*tempElemental = *dynamic_cast<CElemental*>(AllGameObjects[Magma]);
	}
	if( ElementalSouls[Earth] != 0 && ElementalSouls[Water] != 0)
	{
	*tempElemental = *dynamic_cast<CElemental*>(AllGameObjects[Mud]);
	}
	if( ElementalSouls[Earth] != 0 && ElementalSouls[Air] != 0)
	{
	*tempElemental = *dynamic_cast<CElemental*>(AllGameObjects[Sand]);
	}
	if( ElementalSouls[Water] != 0 && ElementalSouls[Fire] != 0)
	{
	*tempElemental = *dynamic_cast<CElemental*>(AllGameObjects[Steam]);
	}
	if( ElementalSouls[Water] != 0 && ElementalSouls[Air] != 0)
	{
	*tempElemental = *dynamic_cast<CElemental*>(AllGameObjects[Storm]);
	}
	if( ElementalSouls[Fire] != 0 && ElementalSouls[Air] != 0)
	{
	*tempElemental = *dynamic_cast<CElemental*>(AllGameObjects[Kamikaze]);
	}

	//Level 3
	if( ElementalSouls[Earth] != 0 && ElementalSouls[Water] != 0 && ElementalSouls[Air] != 0)
	{
	*tempElemental = *dynamic_cast<CElemental*>(AllGameObjects[Everest]);
	}
	if( ElementalSouls[Earth] != 0 && ElementalSouls[Fire] != 0 && ElementalSouls[Air] != 0)
	{
	*tempElemental = *dynamic_cast<CElemental*>(AllGameObjects[Mortar]);
	}
	if( ElementalSouls[Earth] != 0 && ElementalSouls[Fire] != 0 && ElementalSouls[Water] != 0)
	{
	*tempElemental = *dynamic_cast<CElemental*>(AllGameObjects[Metal]);
	}
	if( ElementalSouls[Water] != 0 && ElementalSouls[Fire] != 0 && ElementalSouls[Air] != 0)
	{
	*tempElemental = *dynamic_cast<CElemental*>(AllGameObjects[Hurricane]);
	}


	if( ElementalSouls[Water] != 0 && ElementalSouls[Fire] != 0 && ElementalSouls[Air] != 0 && ElementalSouls[Earth] != 0)
	{
	*tempElemental = *dynamic_cast<CElemental*>(AllGameObjects[Omega]);
	}


	tempElemental->SetElementalSouls(ElementalSouls);
	if( owner->GetPlayer() == true )
	{
	tempElemental->SetPosX(Waypoints[0]->GetPosX());
	tempElemental->SetPosY(Waypoints[0]->GetPosY());
	tempElemental->SetStartWaypoint(Waypoints[0]->GetNext());
	}
	if( owner->GetPlayer() == false )
	{
	tempElemental->SetPosX(Waypoints[Waypoints.size()-1]->GetPosX());
	tempElemental->SetPosY(Waypoints[Waypoints.size()-1]->GetPosY());
	tempElemental->SetStartWaypoint(Waypoints[Waypoints.size()-1]->GetPrev());
	}
	tempElemental->SetOwner(owner);
	if(owner->GetPlayer())
		tempElemental->SetTeam(1);
	else
		tempElemental->SetTeam(2);

	tempElemental->SetLane(laneChoice);

	tempElemental->SetTargetBox(tempElemental->GetPosX(), tempElemental->GetPosY(), tempElemental->GetRange());

	m_pGS->AddElementalToLane(tempElemental, laneChoice);
	m_pOM->AddObject(tempElemental);
	tempElemental->Release();
}

void CObjectFactory::SpawnTower( short towerType, float nX, float nY, int _nTeam )
{
	CTower* tempTower = new CTower;	
	*tempTower = *dynamic_cast<CTower*>(AllGameObjects[Tower]);
	tempTower->SetPosX(nX);
	tempTower->SetPosY(nY);
	tempTower->SetTeam(_nTeam);
	m_pOM->AddObject(tempTower);
	tempTower->Release();
	

}

void CObjectFactory::SpawnNode( float nX, float nY, short nTemp )
{
	CNode* tempNode = new CNode;
	tempNode->SetPosX(nX);
	tempNode->SetPosY(nY);
	tempNode->SetTeam(0);
	tempNode->SetHeight(30); //fix when possible
	tempNode->SetWidth(30);  //fix when possible
	tempNode->SetImageID(3); //fix when possible
	tempNode->SetSoulType(nTemp);
	m_pOM->AddObject(tempNode);
	tempNode->Release();
}

void CObjectFactory::SpawnAvatar( float nX, float nY, int _nTeam )
{
	CAvatar* tempAvatar = new CAvatar;
	tempAvatar->SetPosX(nX);
	tempAvatar->SetPosY(nY);
	tempAvatar->SetTeam(_nTeam);
	tempAvatar->SetHeight(20); //fix when possible
	tempAvatar->SetWidth(20);  //fix when possible
	tempAvatar->SetImageID(Avatar); //fix when possible
	m_pOM->AddObject(tempAvatar);
	tempAvatar->Release();
}

void CObjectFactory::ShutDown(void)
{
	for( OListIterator iter = AllGameObjects.begin(); iter != AllGameObjects.end(); ++iter )
		(*iter)->Release();
	AllGameObjects.clear();
}
